#!/usr/bin/env python
#       uprgae.py
#       
#       Copyright 2008 Edwood Ocasio <edwood.ocasio@gae.cayey.upr.edu>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
#
"""Module to ease management of domains under Google Apps for Education (GAE)."""
import sys
import gettext
import getpass
import os

uprgae_Warnings = ""

_ = gettext.gettext 

try:
	import gdata.apps
	import gdata.apps.service
except:
	uprgae_Warnings = uprgae_Warnings + _("Gdata python module not found. It is required for UPR-GAE console to work!\n")
	sys.exit(1)
	
try:
	from goofs.goofs import GClient
	from goofs.goofs import Goofs
	import goofs
	import fuse
except:
	uprgae_Warnings = uprgae_Warnings + _("Modules 'goofs' or 'fuse' are not installed.  However, you still can use UPR-GAE console ;). \n")
	

import reporting

DEFAULT_LOCALE_DIR="/usr/share/locale"
LANGUAGES=['es','en']
FUTURE_FEATURE=_("This will be a future feature.")
USERLISTFILE='usuarios.gae'

# Name spaces for Google XML schemes
NAMESPACES=['http://www.w3.org/2005/Atom','http://schemas.google.com/apps/2006']

USERNAME_GENERATOR_NUMSEQUENCE=0
USERNAME_GENERATOR_ALPHASEQUENCE=1
USERNAME_GENERATOR_NUMRANDOM=2
USERNAME_GENERATOR_ALPHARANDOM=3

PASSWORD_DEFAULT_LENGTH = 8


REPORTNAMES=['accounts','disk_space','summary','activity','email_clients']

# constants for goofs interface

HOME = None
GOOFS_CACHE = None
PHOTOS = None
PHOTOS_DIR = None
PUB_PHOTOS_DIR = None
PRIV_PHOTOS_DIR = None
GDOCS_DIRS = None
EXT_CTYPE = {'bmp': 'image/bmp', 'gif': 'image/gif', 'png': 'image/png', 'jpg':'image/jpeg', 'jpeg':'image/jpeg'}

__author__ =  'Edwood Ocasio'
__version__=  '0.7'
__email__ = 'edwood.ocasio@gae.cayey.upr.edu'
__firstreleasedate__= '13-Jul-2008'
__releasedate__='01-Sep-2008'
__projecturl__='http://code.google.com/p/uprgae-console/'
__maillist__='http://groups.google.com/group/upr-gae-console'
__license__="GPL v3.0"
		

# goofs integration functions

def mountfs(mountpoint):
	""" Mounts GAE services as a filesystem using 'goofs' module
	
		http://code.google.com/p/goofs
		
	"""
	
	global adminemail

	HOME = os.path.expanduser("~")
	
	# I do not like this line of code but
	# after hours trying to understand the fuse module
	# I gave up ... for now
	
	os.system("python goofs/goofs.py " + mountpoint)

def umountfs(mountpoint):
	""" Dismounts GAE services as a filesystem using 'goofs' module
	
		http://code.google.com/p/goofs
		
	"""

	# I do not like this line of code but
	# after hours trying to understand the fuse module
	# I gave up ... for now
	
	os.system("fusermount -u " + mountpoint)


def about():
	""" Shows uprgae module information. """
	
	print _("UPR-GAE console version ") + __version__
	print __doc__
	print _("License:"),__license__
	print _("Author: "),__author__, "(",__email__,")"
	print _("Release date:"), __releasedate__
	print _("Project url:"), __projecturl__
	print _("Mailing list:"), __maillist__

def cls():
	""" Clears the screen. """
	
	import os
	
	# Try to identify operating system
	
	if os.uname()[0].lower() == 'linux':
		_code=os.system("clear")
	
	else:
		_code=os.system("cls")


def report(report_name, report_date=None, page=None):
	""" Retrieves named report for date specified. 
	
		Available report_names: 
		'accounts','disk_space','summary','activity', 'email_clients'
		
		report_date should be in the format YYYY-MM-DD
		
		If report_date is not specified it returns the latest available 
		report.
		
		If page is None all report pages are retrieved.
		
	"""
	
	import re
	import time
	
	global adminemail
	global domain	
	
	report_runner = reporting.ReportRunner()		
	
  	report_runner.admin_email = adminemail
  	report_runner.admin_password =getpass.getpass(_("Administrator Password: "))
  	report_runner.domain = domain
  	rdate=time.strftime("%a-%d-%b-%Y-%H-%M",time.localtime())
	#file=open("usuarios-" + postfix + ".gae",'a')
	
	if report_date==None:
		out_file_name=report_name + "_" + rdate + "_" + domain + ".csv"
	else:
		out_file_name=report_name + "_" + report_date + "_" + domain +  ".csv"
	#out_file_name=None
	
  	# Date should be in the format YYYY-MM-DD 
  	if (not report_runner.admin_email or not report_runner.admin_password or \
  	not report_name or (report_date is not None and not \
  	re.compile('\d{4}-\d{2}-\d{2}').match(report_date))):
  		print _("Report could not be retrieved")
  	else:
 
  		if page != None:
  			print _("Getting report page "),page, " ..."
  			report_runner.RunReport(report_name, report_date, out_file_name,page_requested=page)
  		else:
  			# Retrieve All Report Pages
  			EndOfReport=False
  			numpage=0
  			while not EndOfReport:
  				numpage = numpage + 1 
  				#debug:print "Page ",numpage
  				
  				print _("Getting report page "), numpage , "..."
  				
				response=report_runner.RunReport(report_name, report_date, out_file_name,page_requested=numpage)
				#EndOfReport= (response == "End-Of-Report")				
				
				if response != None:
					EndOfReport= (response.find("End-Of-Report") >= 0)
				#~ else:
					#~ EndOfReport = True
  		try:		
			for line in open(out_file_name,'r'):
				print line
			
			print _("This report was saved in file '"),out_file_name,"'"
		except:
			print _("This report could not be saved.")
 
 
def printheader():
	"""  Prints administrative console header.
			
	"""
	global consoletitle
	
	print "=========================================================================="
	print "                               UPR-GAE"	
	print _("                       Administrative Console")
	print "                             version " + __version__
	print consoletitle.center(80)
	print "=========================================================================="
	print
	if uprgae_Warnings != "":
		print _("** WARNING **\n")
		print uprgae_Warnings
		print "*****"


def login():
	""" Asks for administrator's credentials. 
	
		Creates object gdata.apps.service.AppsService().
		
	"""
	
	global adminemail
	global domain
	global adminuser
	
	global _service
	
# If we already have the admin email from the gaeconf file
# skip to ask for password
	newemail=adminemail
	
	if newemail == "":
		print _("Before login, this information is needed")
		newemail=raw_input(_("Admin email: "))
		print _("If you want this to be your default email you must set the 'email' parameter in the file 'gaeconf'")
		print 
		
	else:
		print _("The default account seems to be ") + newemail.upper()
		changeit=raw_input(_("Do you want to change it?(y/[n])"))
		
		if changeit.lower() == 'y':
			newemail=raw_input(_("Admin email: "))

	if newemail=="":		
		sys.exit(2)
	
	print _("User : "), newemail.upper()		
	
	_service = gdata.apps.service.AppsService(email=newemail, domain=newemail.split("@")[1],password=getpass.getpass(_("Password: ")))
	
	try:
		_service.ProgrammaticLogin()
		print _("Authentication ... OK")
		adminemail=newemail
		domain=newemail.split("@")[1]
		adminuser=newemail.split("@")[0]
		
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not authenticate account as an administrator.")

		
def loadconf(configfile):
	""" Reads configuration specified file and saves its content in a dictionary.
	
	The configuration file follows this format:
	
		variable1=value1
		variable2=value2
		
	"""
	configuration={}
	try:
		file=open(configfile)		
	except Error,e:
		print _("Configuration file not found.")
		file.close()
		sys.exit(0)	
	
	for line in file:
		tokens=line.split("=")
		try:
			configuration[tokens[0]]=tokens[1].strip("\n")
		except Error,e:
			print e

			
	file.close()

	return configuration

def show(user_name):
	""" Reports all available information from specified user.
	
	Receives _service object created by login()
		
	"""
	if user_name!="":
		try:
			userentry=_service.RetrieveUser(user_name)
			print _('Username        :'),userentry.login.user_name
			print _('Name            :'),userentry.name.given_name,userentry.name.family_name
			print _('Suspended       :'),userentry.login.suspended
			print _('Agreed to terms :'),userentry.login.agreed_to_terms
			print _('Change Password :'),userentry.login.change_password
			print _('Admin User      :'),userentry.login.admin
			print _('Quota (MB)      :'),userentry.quota.limit		
			print _('Title           :'),userentry.title.text
			print _('Last Updated    :'),userentry.updated.text		
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code
	
def get(user_name):
	"""  Returns userentry object for the specified user."""
	
	if user_name!="":
		try:
			userentry=_service.RetrieveUser(user_name)
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code
		
		return userentry

def update(user_name):
	"""  Updates information for specified user . """
	
	if user_name!="":
		try:
			userentry=_service.RetrieveUser(user_name)
	
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code
			
		print _("To keep the current information just press the <ENTER> key.")
		print _("Current name is '") + userentry.name.given_name + "'"
		newname=raw_input(_("New name:"))		
		
		print _("Current family name is '") + userentry.name.family_name + "'"
		newfamilyname=raw_input(_("New family name:"))
			
		print 
		if newname.strip() != '':
			userentry.name.given_name=newname
			print _("Name updated.")
		
		if newfamilyname.strip() != '':
			userentry.name.family_name=newfamilyname
			print _("Family name updated.")
		
	# Ask for changes to user profile
		#~ userentry.name.given_name=newname
		#~ userentry.name.family_name=newfamilyname
		#~ 
		try:
		
			_service.UpdateUser(user_name,userentry)
			
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code		

def setadmin(user_name):
	"""  Sets administration privileges a given user. """
	
	# Warning!
	if user_name == adminuser:
		print "Be careful! You seem to want to remove yourself from the administrators group!"
		goahead=raw_input(_("Is that what you want?(y/[n])"))
		
		if goahead.lower() == 'y':
			print "Let see if it works ..."
		else:
			print "No changes made."
			return None

			
	if user_name!="":
		try:
			userentry=_service.RetrieveUser(user_name)
			if userentry.login.admin=='true':
				toggle=raw_input(_("Remove admin privileges from '") + user_name + "'(y/[n]):")
				if toggle.lower()=='y':
					userentry.login.admin='false'
					try:
						_service.UpdateUser(user_name,userentry)						
						print _("User ") + user_name + _(" is no longer an administrator.")	
					except gdata.apps.service.AppsForYourDomainException,e:
						print e, e.error_code
							
			else:
				toggle=raw_input(_("Give admin privileges to '") + user_name + "'(y/[n]):")
				if toggle.lower()=='y':
					userentry.login.admin='true'
					try:
						_service.UpdateUser(user_name,userentry)
						print _("User ") + user_name + _(" is now an administrator.")		
					except gdata.apps.service.AppsForYourDomainException,e:
						print e, e.error_code
					
		
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code
		
		# update user admin privileges


			

		


def exist(user_name):
	""" Returns True if user exists, False if not """
	
	if user_name !=" ":
		try:
			userentry=_service.RetrieveUser(user_name)
			return True						
		except gdata.apps.service.AppsForYourDomainException,e:
			return False		


	
def genusername(given_name,family_name,generator=USERNAME_GENERATOR_NUMSEQUENCE):
	""" Generates suitable usernames alternatives.
	
		For now only sequential numerical mutation supported:
		
			fulano.sutano3
			fulano.sutano4
			prenseja.merleja99
		
	"""
	
	user_name=given_name + "." + family_name
	if exist(user_name) == True:
		print "'" + user_name + _("' is already taken.")
		print _("Searching for alternatives ...")
		postfix=2
		alter_name =  user_name + str(postfix)
		while exist(alter_name) == True:
			postfix = postfix + 1				
			alter_name = user_name + str(postfix)				
		
		user_name=alter_name
		print "'" + user_name + _("' is available.")
		iexist=False
	else:
		print "'" + user_name + _("' is available.")
		iexist=False
	
	return user_name
	
def create():
	""" Creates a new user. """	
	
	given_name=raw_input(_("Name: "))
	family_name=raw_input(_("Family name: "))
	
	iexist=True
	
	while iexist == True:
		suggestion=given_name.lower() + "." + family_name.lower()
		user_name=raw_input(_("Username [") + suggestion + "]: ")
		if user_name=='':
			user_name=suggestion
			
		if exist(user_name) == True:
			print "'" + user_name + _("' is already taken.")
			
			print _("Searching for alternatives ...")
			postfix=2
			alter_name =  user_name + str(postfix)
			while exist(alter_name) == True:
				postfix = postfix + 1				
				alter_name = user_name + str(postfix)				
			
			user_name=alter_name
			print "'" + user_name + _("' is available.")
			iexist=False
		else:
			print "'" + user_name + _("' is available.")
			iexist=False
			
	password=raw_input(_("Password (6 or more characters ): "))	
	
	if given_name!="" and family_name!="" and user_name!="" and password!="":
		try:
			userentry=_service.CreateUser(user_name, family_name, given_name, password, suspended='false', \
			quota_limit=gdata.apps.service.DEFAULT_QUOTA_LIMIT, password_hash_function=None)
			print _("User ")+ user_name + _(" created.")
			show(user_name)
			# _service.CreateUser(user_name, family_name, given_name, password, 
			# suspended='false', quota_limit=DEFAULT_QUOTA_LIMIT, password_hash_function=None)
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code
			print _("Could not create user ") + user_name 


def delete(user_name):
	""" Deletes user_name account. """
		
	if user_name!="":
		try:
			userentry=_service.DeleteUser(user_name)
			print _("User ") + user_name + _(" account was deleted.")
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code

		

def suspend(user_name):
	""" Suspends user_name account. """
		
	if user_name!="":
		try:
			userentry=_service.SuspendUser(user_name)
			print _("User ") + user_name + _(" account was suspended.")
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code

		

def reactivate(user_name):
	""" Reactivates (restores) specified user after a suspension."""
		
	if user_name!="":
		try:
			userentry=_service.RestoreUser(user_name)
			print _("User ") + user_name + _(" account was reactivated.")
		except gdata.apps.service.AppsForYourDomainException,e:
			print e, e.error_code

		

def chpass(user_name):
	""" Changes user password. """
	
	try:
		user_entry=_service.RetrieveUser(user_name)
		user_entry.login.password=getpass.getpass(_("Password (6 or more characters ): "))
		_service.UpdateUser(user_name, user_entry)
		print _("Password changed.")
	except gdata.apps.service.AppsForYourDomainException , e:
		print _("Password was not changed.")
	
	
	
def search(criteria):
	""" Searches for accounts matching the criteria. 
	
		There is no API to search for accounts in GAE
		so what this function does is search in the most
		recent local list generated by getaccounts() which
		is named 'usuarios.gae' and retrieves a list of
		matches.
		
		This is my first approach to this task.
		
		Possible searching criteria :
		'suspended', 'admin', 'activated'
		
		Anything else is taken as a regular expression that 
		returns a list of matching user_name.
		
	"""

	
	result=[]
	
	
	if criteria=='':
		print _("No search criteria given ('admin','activated','suspended','username regexpr'")
		return None
		
		
	try:
		usersfile=open(USERLISTFILE,'r')
	except:
		print _("Users file not found.")
		return None
		
	
	# Get XML user feed 
	userfeedxml=''
	for line in usersfile:
		userfeedxml=userfeedxml + line
		
	usersfile.close()
	
	# Create UserFeed  object		
	try:
		userlist=gdata.apps.UserFeedFromString(str(userfeedxml))
	except gdata.service.RequestError, e:
		return None
			
	# Get admin users
	if criteria=='admin':
		for usr in userlist.entry:
			if usr.login.admin=='true':
				result.append(usr.login.user_name)
	elif criteria=='suspended':
		for usr in userlist.entry:
			if usr.login.suspended=='true':
				result.append(usr.login.user_name)
	elif criteria=='activated':
		for usr in userlist.entry:
			if usr.login.agreed_to_terms=='true':
				result.append(usr.login.user_name)
	else:
		import re
		rgexp=re.compile(criteria)
		for usr in userlist.entry:
			if rgexp.match(usr.login.user_name.lower()):
				result.append(usr.login.user_name.lower())
	print len(result)
	return result
	


def getallusers():
	"""  Retrieves an XML file with all domain accounts information.  
	
		The file is named using date of creation 
		and replaces the last current users file
		named 'usuarios.gae'.  The XML data corresponds to an UserFeed  
		object containig an XML representation of many UserEntry objects.
		
	"""
	
	import time
	import shutil
	
	print
	print _("Gathering user list for ") + domain
	print

	# Capturar lista de usuarios

	pagina=_service.RetrievePageOfUsers(start_username=None)
	userlist=_service.AddAllElementsFromAllPages(pagina, gdata.apps.UserFeedFromString)

	postfix=time.strftime("%a-%d-%b-%Y-%H-%M",time.localtime())

	outfile="usuarios-" + postfix + ".gae"
	
	file=open(outfile,'w')
	file.write(userlist.ToString())
	file.close()

	shutil.copy(outfile,'usuarios.gae')
	
	print
	print _("List was saved in the file 'usuarios-") + postfix + ".gae'"
	print _("and replaces current user list 'usuarios.gae'.")



def commands():
	""" Retrieves a list of currently supported commands. """
	import inspect	
	print _("Commands available:")
	
	for obj in globals():
		if inspect.isfunction(globals()[obj])==True:
			print obj
				
	print
	print _("Type help(command_name) to get more information about the command")
	print _("Type commands() to retrieve this list again.")
	

def testlogin():
	""" Tests GAE service after login. """
	
	global config
	hbr="****************************\n"
	print "** LOGIN ****************"	
	config=loadconf('gaeconf')
	login()
	try:
		testuser=config['email'].split("@")[0]
		show(testuser)
		if exist(testuser) == True:
			print 
			print "STATUS:  login OK"
	except gdata.apps.service.AppsForYourDomainException,e:
		print e, e.error_code
		
	
def test():
		""" Tests UPR-GAE configuration """
		
		if uprgae_Warnings!="":
			print "@@ WARNING:"
			print uprgae_Warnings
			
		
		hbr="****************************\n"
	
		print "** LOCALE ****************"	
		print "localedir: ", DEFAULT_LOCALE_DIR
		if gettext.find('uprgae',DEFAULT_LOCALE_DIR) != None:			
			for lng in LANGUAGES:
				print lng.upper()
				print gettext.find('uprgae',DEFAULT_LOCALE_DIR,[lng])
			print
			print "STATUS: localedir OK"
		else:
			print "STATUS: {{localedir error!}}"
			
		print hbr
		print "** CONF ****************"
		config=loadconf('gaeconf')
		if config != None:				
			try:
				if config.has_key('email') and config['email'].strip() != '':
					print config['email']
					print config['email'].split("@")[1]
					print config['email'].split("@")[0]
					print "STATUS: email OK"
				else:
					print "STATUS: {{CONF error!}}"
					
				if config.has_key('lang') and config['lang'].strip() != '':
					print config['lang']
					print "STATUS: lang OK"
								
			except Error,e:
				print 'error'
		else:
			print "STATUS: {{CONF error!}}"	
		print hbr
		
		
		#print Goofs(version="%prog " + fuse.__version__,dash_s_do='setsingle').statfs()

		
		about()
		

def createlist(list_name):
	""" Creates empty email list with given name. """
	
	try:
		_service.CreateEmailList(list_name)
		print _("List ") + list_name + _(" was created. ")
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not create list ") +  list_name
		print e

def deletelist(list_name):
	""" Deletes email list with given name. """
	
	try:
		_service.DeleteEmailList(list_name)
		print _("List ") + list_name + _(" was deleted. ")
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not delete list ") +  list_name
		print e


def getlist(list_name):
	"""  Returns EmailListEntry object for the specified list."""	
	try:
		_list=_service.RetrieveEmailList(list_name)
		return _list
		
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not delete list ") +  list_name
		print e


def addtolist(user_name,list_name):
	""" Adds  specified user to list list_name. """
	
	try:
		_service.AddRecipientToEmailList(user_name,list_name)			
		print _("Added"),user_name,_("to"),list_name,_("list.")
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not add user to list.")


def removefromlist(user_name,list_name):
	""" Removes specified user from list list_name. """
	
	try:
		_service.RemoveRecipientFromEmailList(user_name,list_name)			
		print _("Removed"),user_name,_("from"),list_name,_("list.")
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not remove user from list.")
	
def getmemberlist(list_name):
	""" Gets all members of the specified list in an EmailListRecipientFeed obect. 
	
		Returns a list with user_name of members.
		
	"""
	
	try:
		_members=_service.RetrieveAllRecipients(list_name)
		
		memberlist=[]
		for member in _members.entry:
			memberlist.append(member.who.email)
			
		return memberlist
		
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not retrieve members list.")

def addtolistf(filename,list_name):
	""" Adds members to list_name from a file.
	
	Adds users from specified file as members of a list. The file should
	contain COMPLETE EMAIL addresses, one per line:
	
	fulano.sutano@gmail.com
	prensejo.merlejo@gae.cayey.upr.edu
	
	"""
	
	if filename == "":
		print _("File name is required.")
		sys.exit(2)

	try:
		file=open(filename,'r')
		for line in file:
			user_name=line.strip("\n")
			print user_name
			_service.AddRecipientToEmailList(user_name,list_name)
			print _("Account ") + user_name + _(" was added to list ") + list_name
		
		file.close()
			
	except gdata.apps.service.AppsForYourDomainException,e:
		print e, e.error_code
		print _("Account ") + user_name + _(" could not be added to list.")


def exportlist(list_name,filename='export.csv',delimiter="\n"):
	""" Exports specified email list member addresses to a file. 
	
		It uses the new line character as default ('\n') which produces
		a file with ONE EMAIL per line. Any delimiter can be specified.
		
		If file name is not given it defaults to 'export.csv'
	
	"""
	
	try:
		_members=_service.RetrieveAllRecipients(list_name)
		
		export=open(filename,'w')
		
		memberlist=[]
		for member in _members.entry:
			export.write(member.who.email + delimiter)
			
		print 	
		print _("Saved to file ") + filename
		export.close()
		
		print _("File content:")
		
		for l in open(filename,'r'):
			print l
		
		
	except (gdata.apps.service.AppsForYourDomainException) , e:
		print _("Could not export members list.")
	


def createf(filename,listonly=False):
	""" Create users from a file.
	
	Creates users from specified file in batchmode. The file is in a 
	CSV format following this conventions:
	
	The file should contain the given name of the user and her family
	name separated by comas:
	
		Fulano, Sutano
		
	The function will assign a suitable username and password. It will
	also create a file with the account information.
	
	"""
	
	# csv module needed to better handle the required csv file
	import csv
		
	if filename == "":
		print _("File name is required.")
		sys.exit(2)
	
	outfile=open('out_' + filename,'w')		
	outfile.close()
	
	
	file=csv.reader(open(filename,'r'))	
	for line in file:
		given_name=line[0].strip("\n")
		family_name=line[1].strip("\n")
		user_name=genusername(given_name.strip().lower(),family_name.strip().lower(),USERNAME_GENERATOR_NUMSEQUENCE)
		password=genpassword()
	
		print user_name			

		if not listonly:
			try:
				userentry=_service.CreateUser(user_name, family_name, given_name, password, suspended='false', \
				quota_limit=gdata.apps.service.DEFAULT_QUOTA_LIMIT, password_hash_function=None)
				print _("User ") + user_name + _(" was created.")
				outfile=open('out_' + filename,'a')
				outfile.write(user_name + "," + given_name + "," + family_name + "," + password + "\n")
				outfile.close()				
			except gdata.apps.service.AppsForYourDomainException,e:
					print e.error_code
					print _("User ") + user_name + _(" could not be created.")
			


		
def deletef(filename):
	""" Delete users listed in a file.
	
	Deletes users from specified file in batchmode. The file should
	contain only the usernames, one per line:
	
	fulano.sutano
	prensejo.merlejo	
	
	"""
	
	if filename == "":
		print _("File name is required.")
		sys.exit(2)

	try:
		file=open(filename,'r')
		for line in file:
			user_name=line.strip("\n")
			print user_name
			userentry=_service.DeleteUser(user_name)
			print _("Account ") + user_name + _(" was deleted.")	
		
		file.close()
			
	except gdata.apps.service.AppsForYourDomainException,e:
		print e, e.error_code
		print _("Account ") + user_name + _(" could not be deleted.")

		
def suspendf(filename):
	""" Suspends users listed in a file.
	
	Suspends users from specified file in batchmode. The file should
	contain only the usernames, one per line:
	
	fulano.sutano
	prensejo.merlejo	
	
	"""
	
	if filename == "":
		print _("File name is required.")
		sys.exit(2)

	try:
		file=open(filename,'r')
		for line in file:
			user_name=line.strip("\n")
			print user_name
			userentry=_service.SuspendUser(user_name)
			print _("Account ") + user_name + _(" was suspended.")		
		
		file.close()
			
	except gdata.apps.service.AppsForYourDomainException,e:
		print e, e.error_code
		print _("Account ") + user_name + _(" could not be suspended.")


def reactivatef(filename):
	""" Reactivates users listed in a file.
	
	Reactivates users from specified file in batchmode. The file should
	contain only the usernames, one per line:
	
	fulano.sutano
	prensejo.merlejo	
	
	"""
	
	if filename == "":
		print _("File name is required.")
		sys.exit(2)

	try:
		file=open(filename,'r')
		for line in file:
			user_name=line.strip("\n")
			print user_name
			userentry=_service.RestoreUser(user_name)
			print _("Account ") + user_name + _(" was reactivated.")
			
		
		file.close()
			
	except gdata.apps.service.AppsForYourDomainException,e:
		print e, e.error_code
		print _("Account ") + user_name + _(" could not be reactivated.")


def genpassword():
	""" Password generator. 
	
	Simple password generator based on code from this url:
	
	http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473852
	
	Thanks to the author (anonymous).
	
	"""
	
	from random import Random
	rng = Random()
	alternate_hands=True
	righthand = '23456qwertasdfgzxcvobQWERTASDFGZXCVB'
	lefthand = '789yuiophajknmYUIPHJKLNM'
	allchars = righthand + lefthand
	# debug: print allchars
	passwordLength = PASSWORD_DEFAULT_LENGTH
	#debug: print passwordLength
	newpassword=""
	for i in range(passwordLength):
		if not alternate_hands:
			newpassword += rng.choice(allchars)
		else:
			if i%2: 
			
				newpassword += rng.choice(lefthand)
			else:
				newpassword += rng.choice(righthand)
	
	return newpassword

def setlang(lang):
	global _
	
	import gettext
	localedir=gettext.bindtextdomain('uprgae',DEFAULT_LOCALE_DIR)
	textdomain=gettext.textdomain('uprgae')	
	
	try:
		t = gettext.translation(textdomain, localedir,languages=[lang])
	except:
		t = gettext.translation(textdomain, localedir,languages=['en'])
	#~ import locale
	#~ locale.setlocale(locale.LC_ALL,'es_ES')

	_ = t.lgettext
		



"""

Main routine of the module

"""

if __name__ == '__main__':

# Put module tests here
# This will execute if you run 'uprgae.py'
# as a script:
# 	python ./uprgae.py
#
	test()

# Uncomment next line to test login to your doomain
#	testlogin()
	pass	
	
else:
#	 This will be executed in case the
#	    source has been imported as a
#	    module.

# Initialization
	
	
	global adminemail
	global domain
	global adminuser
	global gaefs
	
	gaefs=None
	
	config=loadconf('gaeconf')
	adminemail=''
	domain=''
	adminuser=''
	
	
	if config.has_key('email')==True:
		adminemail=config['email']
		if adminemail.strip() != '':
			domain=config['email'].split("@")[1]
			adminuser=config['email'].split("@")[0]
	
	if config.has_key('lang')==True:
		lang=config['lang']
		setlang(lang)
		
	if config.has_key('title')==True:
		consoletitle=config['title']
	
		if consoletitle.strip() == '':
			consoletitle="<This title line can be customized in file 'gaeconf'>"
	
  
